/*
 * SubServerListener.java
 *
 * Created on August 11, 2006, 4:42 PM
 *
 */
package org.letva.copie.subserver.listeners;

import java.io.*;
import java.net.*;
import java.util.*;
import org.letva.copie.common.message.SubServerInfo;
import org.letva.copie.subserver.*;
import org.letva.copie.subserver.threads.SubServerThread;

/**
 * Nit koja osluskuje na odredjenom portu da li hoce neki drugi SubServer da se poveze
 * na njega, da bi napravio novu nit koja ce mu poslati sadrzaj svog Clipboarda
 * @author Vuk Nikolic
 */
public class SubServerListener extends Thread {

	/**
	 * Creates a new instance of SubServerListener
	 * @param ss
	 */
	public SubServerListener(SubServer ss) {
		super("SubServerListner");
		mySubServer = ss;
		mySubServer.writeLog("SubServerListener created.");
	}

	@Override
	public void run() {
		System.out.println("SubServerListener: poceo run");
		// prvo da napravimo serverski socket
		try {
			serverSocket = new ServerSocket(mySubServer.getSubServerPort());
			mySubServer.writeLog("SubServerListener: Server socket created.");
			// napravili smo serverski socket
		} catch (IOException e) {
			// posto nije uspeo da otvori port za podservere, da bi aktivirali dugme
			// za aktiviranje moram da gasimo i clientListener
			mySubServer.writeLog("SubServerListener: ERROR: Server socket not created.");
			mySubServer.stopClientListener();
			mySubServer.getMyWindow().setActivateSubServerItem(true);
			theEnd = true;
			mySubServer.getMyWindow().setDialogException("Connection Error", "Cannot connect to port: " + mySubServer.getSubServerPort());
		}


		// e sada da prihvatimo nove konekcije
		while (!theEnd) {
			try {
				socket = serverSocket.accept(); // blokira se dok neko ne uspostavi vezu
				mySubServer.writeLog("SubServerListener: new subserver trying to connect: " + socket.getInetAddress());

				// cim je prosao accept znaci neko hoce da uspostavi vezu
				// prepoznajem ga po ip adresi, a port je popularni
				// mySubServer.getPort()
				String subServerUrl = socket.getInetAddress().toString();
				// da vidimo da li je taj vec prijavljen

				if (mySubServer.getConnectedSubServers().containsKey(subServerUrl) == false) {
					// ako nije dodajemo ga u listu prijavljenih
					SubServerInfo ssinfo = new SubServerInfo(subServerUrl, socket.getPort());

					// sada je to synch metoda tako da ne treba da brinemo.
					mySubServer.addConnectedSubServer(ssinfo);

					Thread t = new SubServerThread(socket, mySubServer);
					mySubServer.incActiveSubServerThreads();
					t.start();

					mySubServer.writeLog("SubServerListener: Subserver " + socket.getInetAddress() + " connected.");
				} else {
					mySubServer.writeLog("SubServerListener: Subserver " + socket.getInetAddress() + " already connected.");
					try {
						socket.close();
					} catch (IOException ex) {
						ex.printStackTrace();
					}
				}
			} catch (SocketException ex) {
				mySubServer.writeLog("SubServerListener: SocketException: " + ex);
				mySubServer.getMyWindow().setDialogException("Connection Error", "Connection problems with subserver");
			} catch (SocketTimeoutException ex) {
				mySubServer.writeLog("SubServerListener: SocketTimeoutException: " + ex);
				mySubServer.getMyWindow().setDialogException("Connection Error", "Subserver timeout!");
			} catch (IOException e) {
				mySubServer.writeLog("SubServerListener: IOException: " + e);
				mySubServer.getMyWindow().setDialogException("Connection Error", "Problems with input/output operations");
			}
		}

		System.out.println("SubServerListener: gotov run");
		try {
			if (serverSocket != null) {
				serverSocket.close();
			}
			if (socket != null) {
				socket.close();
			}
		} catch (IOException ex) {
			ex.printStackTrace();
		}

	}

	public void stopSubServerListener() {
		theEnd = false;
	}

	public LinkedList getThreads() {
		return threads;
	}
	// za identifikaciju listnera
	private static int totalId = 0;
	private int id = ++totalId;
	// threadovi koji rade sa podserverima
	private LinkedList threads = new LinkedList();
	// soket ka novom subserveru
	private Socket socket = null;
	// serverski socket
	private ServerSocket serverSocket = null;
	// da li idalje nit da radi?
	boolean theEnd = false;
	// referenca ka subserveru
	private SubServer mySubServer = null;
}
